package com.lakers.notice.springboot.netty;

import com.lakers.notice.springboot.netty.processor.AbstractMessageProcessor;
import com.lakers.notice.springboot.netty.processor.ProcessorFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * 功能描述: NoticeChannelHandler
 *
 * @author liqin(zxl)
 * @date 2024/5/3
 */
@Slf4j
public class NoticeChannelHandler extends SimpleChannelInboundHandler<SendInfo> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, SendInfo sendInfo) throws Exception {
        final CmdType cmdType = CmdType.fromCode(sendInfo.getCmd());
        if (Objects.isNull(cmdType)){
            log.warn("not found cmd type, type is:{}", sendInfo.getCmd());
            return;
        }
        AbstractMessageProcessor processor = ProcessorFactory.createProcessor(cmdType);
        processor.process(ctx, processor.transForm(sendInfo.getContent()));
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            if (state == IdleState.READER_IDLE) {
                AttributeKey<Long> attr = AttributeKey.valueOf("USER_ID");
                Long userId = ctx.channel().attr(attr).get();
                AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
                Integer terminal = ctx.channel().attr(terminalAttr).get();
                log.info("心跳超时，即将断开连接,用户id:{},终端类型:{} ", userId, terminal);
                ctx.channel().close();
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().id().asLongText() + " connect");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        AttributeKey<String> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID);
        String userId = ctx.channel().attr(userIdAttr).get();
        AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
        Integer terminal = ctx.channel().attr(terminalAttr).get();
        ChannelHandlerContext context = UserChannelCtxMap.getChannelCtx(userId, terminal);
        if (context != null && ctx.channel().id().equals(context.channel().id())) {
            UserChannelCtxMap.removeChannelCtx(userId, terminal);
            log.info("断开连接,userId:{},终端类型:{}", userId, terminal);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error(cause.getMessage());
    }
}
